/************************************************************************
 *				SRLOS Team CopyRight
 *@file		task.h
 *@author	bloceanc
 *@date		7/17/2010
 *@note		task managerment
 ************************************************************************/

#ifndef	_TASK_H_
#define	_TASK_H_

#include "mt_mutex.h"			// for mutex
#include "mem_processmmu.h"		// for process memory

// thread state
#define	TASK_THREAD_STATE_RUNNING	0x0	/* thread is running in its process 
											but not sure is g_current_thread */
#define	TASK_THREAD_STATE_RUNABLE	0x1	/* thread can running anytime */
#define	TASK_THREAD_STATE_SUSPEND	0x2	/* thread suspend now, can't run before resume it */
#define	TASK_THREAD_STATE_WAITTING	0x3	/* watting for mutex or other object */
#define	TASK_THREAD_STATE_CREATE	0x4	/* thread which just created */
#define TASK_THREAD_STATE_TERMINATE 0x5 /* thread is terminated, but need to free TCB */
#define TASK_THREAD_STATE_ALARM		0x6 /* thread is waitting alarm  */

// process state
#define TASK_PROCESS_STATE_RUNNABLE  0x6 /* process can run anytime */
#define TASK_PROCESS_STATE_TERMINATE 0x7 /* process will be terminated */

// thread type
#define TASK_THREAD_TYPE_NORMAL 0xB /* Normal thread of process  */
#define TASK_THREAD_TYPE_MAIN	0xA	/* Main thread of process */

// thread priority
#define TASK_PRIORITY_HIGHEST	0x4 /* the highest priority */
#define	TASK_PRIORITY_HIGH		0x3 /* the high priotity */
#define TASK_PRIORITY_NORMAL	0x2 /* normal priotity */
#define TASK_PRIORITY_LOW		0x1 /* low priotity */
#define TASK_PRIORITY_LOWES		0x0 /* lowest priotity */

// thread schedule macros
// thread switch macros
// macros for save/load/new cpu contex to kernel mode stack
// save thread context, we'd not better save SPSR, because there is no SPSR in _sys mode
#define	TASK_CPU_CONTEXT_SAVE(__thread__,__ret_addr__)		\
	__asm__ __volatile__(   					\
		"STMFD R13!,{%1}\n\t"						\
		"STMFD R13!,{R0-R12,R14}\n\t"			\
		"MRS R0, CPSR\n\t"						\
		"STMFD R13!, {R0}\n\t"					\
		"MOV %0, R13\n\t"						\
		:"=r"(__thread__->kernel_sp):"r"(__ret_addr__):"r0","memory"		\
		)



// resume thread context
#define TASK_CPU_CONTEXT_RESUME(__thread__)	\
	__asm__ __volatile__(			    		\
		"MOV R13, %0\n\t"						\
		"LDMFD R13!, {R0}\n\t"					\
		"MSR CPSR, R0\n\t"						\
		"LDMFD R13!,{R0-R12,R14}\n\t"			\
		"LDMFD R13!,{R15}\n\t"		\
		::"r"(__thread__->kernel_sp):"r0","memory","cc"			\
	)

struct process_struct;

// thread context block
typedef struct thread_struct{
	/* mutex field , this support multy mutex lock, following fields will be used only when thread lock failed
	   and have to waitting, a thread only can wait once time at the same time, so this is enough for multi
	   mutex lock */
	k_mutex		*mutex_wait;	/* indicating which mutex this thread waitting if not NULL */
	unsigned int mutex_depth;	/* current mutex lock depth */
	struct thread_struct *wait_next;	/* mutex waitting list, used in mutex */
	struct thread_struct *wait_prev;	/* mutex waitting list, used in mutex */
	long long mutex_overtime;	/* overtime of waitting mutex, -1 means forever */
	
	/* thread list field */
	struct thread_struct *next;	/* next thread block */
	struct thread_struct *prev;	/* previous thread block */
	
	unsigned int state;	/* thread state */
	
	/* thread cpu context, saved in kernel mode statck */
	unsigned int kernel_sp; /* system mode stack top pointer  */

	/* thread current priority */
	unsigned short cur_priority;
	/* thread fixed priority */
	unsigned short fix_priority;
	
	/* thread type  */
	unsigned int type;
	/* thread id  */
	unsigned int id;

	/* user mode stack base pointer */
	unsigned int usr_stack;		/* NOTE: if this is a system mode thread, there will not be this field, system mode thread always use sys_stack, never using usr_stack */
	/* system mode stack base pointer */
	unsigned int sys_stack;

	/* thread sleep time */
	long long alamtime;

	struct process_struct *process; /* process  */
}k_thread;

// process context block
typedef struct process_struct{	
	/** memory info */
	mem_info	mem;
	
	/** thread lock */
	k_mutex	thread_mutex;	/* 使用这个我们就可以再不使用全局锁的情况下来实现进程内部线程之间的同步控制 */
	
	/** thread list */
	k_thread *thread_running;	/* current running thread in process, but should not be g_current_thread */
	k_thread *thread_runable;	/* threads can be run anytime */
	k_thread *thread_suspend;	/* threads suspended, need resume */
	k_thread *thread_alarm;		/* thread that wait alarm, sleep */
	k_thread *thread_waitting;	/* threads waitting for mutex */
	k_thread *thread_terminating; /* threads need to terminate(free TCB) */

	/* process current priority */
	unsigned int runable_thread_count; /* runable thread count, this judge the cpu timesilice of current process, more
										  runable thread more cpu timesilice */
	unsigned short cur_priority;
	unsigned short fix_priority;

	/* process list module */
	struct process_struct *next;
	struct process_struct *prev;
	
	/* share page , used for process commnunication */
	process_share_page	*share_page;
	
	/* parent process */
	struct process_struct *parent;
	
	/* PID */
	unsigned int pid;

	/* process state */
	int state;
}k_process;

#endif	/* _TASK_H_ */
